package com.hospital.workstation.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hospital.common.core.domain.PageQuery;
import com.hospital.common.core.domain.R;
import com.hospital.common.core.page.TableDataInfo;
import com.hospital.common.exception.ServiceException;
import com.hospital.common.utils.StringUtils;
import com.hospital.workstation.constant.DictConstants;
import com.hospital.workstation.domain.*;
import com.hospital.workstation.domain.bo.ElectronicManagerInfoBo;
import com.hospital.workstation.domain.vo.*;
import com.hospital.workstation.domain.vo.json.BasicMonitorOneVo;
import com.hospital.workstation.domain.vo.json.CombindMedicalVo;
import com.hospital.workstation.domain.vo.json.DailyMedicalVo;
import com.hospital.workstation.domain.vo.json.ExportMonitorJsonVo;
import com.hospital.workstation.mapper.*;
import com.hospital.workstation.service.IElectronicManagerInfoService;
import com.hospital.workstation.service.IElectronicMonitorOneInfoService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.rmi.ServerException;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 电子监测管理信息Service业务层处理
 *
 * @author whb
 * @date 2024-04-30
 */
@RequiredArgsConstructor
@Service
public class ElectronicManagerInfoServiceImpl implements IElectronicManagerInfoService {

    private final ElectronicManagerInfoMapper baseMapper;
    private final PatientBaseInfoMapper patientBaseInfoMapper;
    private final ElectronicMonitorOneInfoMapper monitorOneInfoMapper;
    private final ElectronicExtendOneInfoMapper extendOneInfoMapper;
    private final ElectronicExtendTwoInfoMapper extendTwoInfoMapper;
    private final ElectronicMonitorTwoInfoMapper monitorTwoInfoMapper;
    private final ElectronicBadRecordInfoMapper badRecordInfoMapper;
    private final IElectronicMonitorOneInfoService iElectronicMonitorOneInfoService;
    @Resource
    private ObjectMapper objectMapper;

    /**
     * 查询电子监测管理信息（A表）
     */
    @Override
    public ElectronicMonitorOneInfoVo queryById(Long id) {
        // 1.查询监测管理信息
        ElectronicManagerInfoVo electronicManagerInfoVo = baseMapper.selectVoById(id);
        // 2.查询
        ElectronicMonitorOneInfoVo electronicMonitorOneInfoVo = null;
        if (StringUtils.equals(electronicManagerInfoVo.getIsInputForm(), DictConstants.IS_INPUT_FORM_N)) {
            // 2.1 未入组
            electronicMonitorOneInfoVo = new ElectronicMonitorOneInfoVo();
            // 2.2 查询患者基本信息
            PatientBaseInfo patientBaseInfo = patientBaseInfoMapper.selectOne(new LambdaQueryWrapper<PatientBaseInfo>()
                .eq(PatientBaseInfo::getMedicalRecordNo, electronicManagerInfoVo.getMedicalRecordNo()));
            if (ObjectUtil.isNull(patientBaseInfo)) {
                throw new ServiceException("患者已不存在");
            } else {
                // 患者姓名缩写
                String acronymName = StringUtils.getChinesePerLetterToUpper(patientBaseInfo.getPatientName());
                electronicMonitorOneInfoVo.setPatientNameAcronym(StringUtils.retainDefaultLength(4, acronymName, "*"));
                // 住院号
                //electronicMonitorOneInfoVo.setPatientNo("AA" + patientBaseInfo.getMedicareNo());
                electronicMonitorOneInfoVo.setPatientNo(StringUtils.padl(patientBaseInfo.getMedicareNo(), 10, 'A'));
                // 性别
                electronicMonitorOneInfoVo.setPatientSex(patientBaseInfo.getPatientSex());
                // 出生日期
                electronicMonitorOneInfoVo.setBirthdate(patientBaseInfo.getBirthdate());
                // 联系电话
                electronicMonitorOneInfoVo.setPhoneNo(patientBaseInfo.getPhoneNo());
                // 身高
                electronicMonitorOneInfoVo.setPatientHeight(patientBaseInfo.getPatientHeight());
                // 体重
                electronicMonitorOneInfoVo.setPatientWeight(patientBaseInfo.getPatientWeight());
                // 民族
                electronicMonitorOneInfoVo.setNation(patientBaseInfo.getNation());
                // 入院诊断
                Map diagMap = iElectronicMonitorOneInfoService.queryDiagInfo(patientBaseInfo.getMedicalRecordNo());
                electronicMonitorOneInfoVo.setWesternAdmittingDiagnose((String) diagMap.get("west"));
                String traditionalDiagInfo = (String) diagMap.get("traditional");
                String syndromeDiagInfo = (String) diagMap.get("syndrome");
                if (ObjectUtil.isNotNull(traditionalDiagInfo)) {
                    electronicMonitorOneInfoVo.setIsHaveTcmAdmittingDiagnose("1");
                    electronicMonitorOneInfoVo.setTcmAdmittingDiagnose(traditionalDiagInfo);
                } else {
                    electronicMonitorOneInfoVo.setIsHaveTcmAdmittingDiagnose("0");
                }
                if (ObjectUtil.isNotNull(syndromeDiagInfo)) {
                    electronicMonitorOneInfoVo.setIsHaveAdmittingDialectical("1");
                    electronicMonitorOneInfoVo.setAdmittingDialecticalDetail(syndromeDiagInfo);
                } else {
                    electronicMonitorOneInfoVo.setIsHaveAdmittingDialectical("0");
                }
            }

        } else {
            // 2.2 已入组
            Long monitorId = electronicManagerInfoVo.getMonitorId();
            if (ObjectUtil.isNull(monitorId)) {
                throw new ServiceException("已入组A表信息的监测id为空");
            }
            electronicMonitorOneInfoVo = monitorOneInfoMapper.selectVoById(monitorId);
            if (ObjectUtil.isNull(electronicMonitorOneInfoVo)) {
                throw new ServiceException("已入组A表信息已不存在");
            }
            // 2.3 查询续一表数据
            List<ElectronicExtendOneInfoVo> electronicExtendOneInfoVoList = extendOneInfoMapper.selectVoList(new LambdaQueryWrapper<ElectronicExtendOneInfo>()
                .eq(ElectronicExtendOneInfo::getMonitorId, monitorId));
            electronicMonitorOneInfoVo.setElectronicExtendOneInfoVoList(electronicExtendOneInfoVoList);
            // 2.4 查询续二表数据
            List<ElectronicExtendTwoInfoVo> electronicExtendTwoInfoVoList = extendTwoInfoMapper.selectVoList(new LambdaQueryWrapper<ElectronicExtendTwoInfo>()
                .eq(ElectronicExtendTwoInfo::getMonitorId, monitorId));
            electronicMonitorOneInfoVo.setElectronicExtendTwoInfoVoList(electronicExtendTwoInfoVoList);
        }
        electronicMonitorOneInfoVo.setManageId(electronicManagerInfoVo.getId());
        return electronicMonitorOneInfoVo;
    }

    /**
     * 查询电子监测管理信息列表
     */
    @Override
    public TableDataInfo<ElectronicManagerInfoVo> queryPageList(ElectronicManagerInfoBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ElectronicManagerInfo> lqw = buildQueryWrapper(bo);
        lqw.orderByAsc(ElectronicManagerInfo::getIsInputForm)
            .orderByDesc(ElectronicManagerInfo::getUpdateTime);
        Page<ElectronicManagerInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询电子监测管理信息列表
     */
    @Override
    public List<ElectronicManagerInfoVo> queryList(ElectronicManagerInfoBo bo) {
        LambdaQueryWrapper<ElectronicManagerInfo> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ElectronicManagerInfo> buildQueryWrapper(ElectronicManagerInfoBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ElectronicManagerInfo> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getMedicalRecordNo() != null, ElectronicManagerInfo::getMedicalRecordNo, bo.getMedicalRecordNo());
        lqw.eq(bo.getMonitorId() != null, ElectronicManagerInfo::getMonitorId, bo.getMonitorId());
        lqw.eq(bo.getMonitorRecordNo() != null, ElectronicManagerInfo::getMonitorRecordNo, bo.getMonitorRecordNo());
        lqw.eq(StringUtils.isNotBlank(bo.getMonitorTableType()), ElectronicManagerInfo::getMonitorTableType, bo.getMonitorTableType());
        lqw.eq(bo.getInputFormDate() != null, ElectronicManagerInfo::getInputFormDate, bo.getInputFormDate());
        lqw.eq(StringUtils.isNotBlank(bo.getIsInputForm()), ElectronicManagerInfo::getIsInputForm, bo.getIsInputForm());
        return lqw;
    }

    /**
     * 新增电子监测管理信息
     */
    @Override
    public R<Void> insertByBo(ElectronicManagerInfoBo bo) {
        // 1.查询未入组的电子监测表
        ElectronicManagerInfo electronicManagerInfo = baseMapper.selectOne(new LambdaQueryWrapper<ElectronicManagerInfo>()
            .eq(ElectronicManagerInfo::getMedicalRecordNo, bo.getMedicalRecordNo())
            .eq(ElectronicManagerInfo::getMonitorTableType, bo.getMonitorTableType())
            .eq(ElectronicManagerInfo::getIsInputForm, DictConstants.IS_INPUT_FORM_N));
        if (ObjectUtil.isNotNull(electronicManagerInfo)) {
            if (StringUtils.equals(bo.getMonitorTableType(), DictConstants.MONITOR_TABLE_TYPE_A)) {
                return R.fail("有未入组的A表，不能新增");
            } else {
                return R.fail("有未入组的B表，不能新增");
            }
        }
        // 2.新增电子监测表
        ElectronicManagerInfo add = BeanUtil.toBean(bo, ElectronicManagerInfo.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (!flag) {
            return R.fail("新增失败");
        }
        // 3.设置患者信息存在电子监测表
        PatientBaseInfo patientBaseInfo = patientBaseInfoMapper.selectOne(new LambdaQueryWrapper<PatientBaseInfo>()
            .eq(PatientBaseInfo::getMedicalRecordNo, bo.getMedicalRecordNo()));
        patientBaseInfo.setIsHaveMonitor("1");
        flag = patientBaseInfoMapper.updateById(patientBaseInfo) > 0;
        if (!flag) {
            throw new ServiceException("修改患者信息失败");
        }
        return R.ok("新增成功");
    }

    /**
     * 修改电子监测管理信息
     */
    @Override
    public Boolean updateByBo(ElectronicManagerInfoBo bo) {
        ElectronicManagerInfo update = BeanUtil.toBean(bo, ElectronicManagerInfo.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ElectronicManagerInfo entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除电子监测管理信息
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 删除（A表）
     *
     * @param id 监测管理主键id
     * @return
     */
    @Transactional
    @Override
    public R<Void> deleteById(Long id) {
        boolean flag = false;
        // 1.查询监测管理信息
        ElectronicManagerInfo electronicManagerInfo = baseMapper.selectById(id);
        // 2.删除监测管理信息
        flag = baseMapper.deleteById(id) > 0;
        if (!flag) {
            throw new ServiceException("删除监测管理信息异常");
        }
        // 3.已入组
        Long monitorId = electronicManagerInfo.getMonitorId();
        /*if (ObjectUtil.isNull(monitorId)) {
            throw new ServiceException("没有查询到监测表id");
        }*/
        if (ObjectUtil.isNotNull(monitorId) && StringUtils.equals(electronicManagerInfo.getIsInputForm(), DictConstants.IS_INPUT_FORM_Y)) {
            // 3.1 删除监测A表信息
            flag = monitorOneInfoMapper.deleteById(monitorId) > 0;
            if (!flag) {
                throw new ServiceException("删除监测A表信息异常");
            }
            // 3.2 删除续一表信息
            try {
                extendOneInfoMapper.delete(new LambdaQueryWrapper<ElectronicExtendOneInfo>()
                    .eq(ElectronicExtendOneInfo::getMonitorId, monitorId));
            } catch (Exception e) {
                throw new ServiceException("删除续一表信息异常");
            }
            // 3.3 删除续二表信息
            try {
                extendTwoInfoMapper.delete(new LambdaQueryWrapper<ElectronicExtendTwoInfo>()
                    .eq(ElectronicExtendTwoInfo::getMonitorId, monitorId));
            } catch (Exception e) {
                throw new ServiceException("删除续二表信息异常");
            }
        }
        // 4.修改患者基本信息
        Integer medicalRecordNo = electronicManagerInfo.getMedicalRecordNo();
        List<ElectronicManagerInfo> electronicManagerInfoList = baseMapper.selectList(new LambdaQueryWrapper<ElectronicManagerInfo>()
            .eq(ElectronicManagerInfo::getMedicalRecordNo, medicalRecordNo));
        if (electronicManagerInfoList.size() == 0) {
            PatientBaseInfo patientBaseInfo = patientBaseInfoMapper.selectOne(new LambdaQueryWrapper<PatientBaseInfo>()
                .eq(PatientBaseInfo::getMedicalRecordNo, medicalRecordNo));
            patientBaseInfo.setIsHaveMonitor("0");
            flag = patientBaseInfoMapper.updateById(patientBaseInfo) > 0;
            if (!flag) {
                throw new ServiceException("修改患者信息失败");
            }
        }
        return R.ok("删除成功");
    }

    /**
     * 查询管理信息详细信息（B表）
     *
     * @param id 主键
     * @return
     */
    @Override
    public ElectronicMonitorTwoInfoVo queryMonitorTwoInfoById(Long id) {
        // 1.查询监测管理信息
        ElectronicManagerInfoVo electronicManagerInfoVo = baseMapper.selectVoById(id);
        // 2.查询
        ElectronicMonitorTwoInfoVo electronicMonitorTwoInfoVo = null;
        if (StringUtils.equals(electronicManagerInfoVo.getIsInputForm(), DictConstants.IS_INPUT_FORM_N)) {
            // 2.1 未入组
            electronicMonitorTwoInfoVo = new ElectronicMonitorTwoInfoVo();
            // 2.2 查询患者基本信息
            PatientBaseInfo patientBaseInfo = patientBaseInfoMapper.selectOne(new LambdaQueryWrapper<PatientBaseInfo>()
                .eq(PatientBaseInfo::getMedicalRecordNo, electronicManagerInfoVo.getMedicalRecordNo()));
            if (ObjectUtil.isNull(patientBaseInfo)) {
                throw new ServiceException("患者已不存在");
            } else {
                // 住院号
                //electronicMonitorTwoInfoVo.setPatientNo("AA" + patientBaseInfo.getMedicareNo());
                electronicMonitorTwoInfoVo.setPatientNo(StringUtils.padl(patientBaseInfo.getMedicareNo(), 10, 'A'));
                // 患者姓名缩写
                String acronymName = StringUtils.getChinesePerLetterToUpper(patientBaseInfo.getPatientName());
                electronicMonitorTwoInfoVo.setPatientNameAcronym(StringUtils.retainDefaultLength(4, acronymName, "*"));
                // 患者姓名
                electronicMonitorTwoInfoVo.setPatientName(patientBaseInfo.getPatientName());
                // 性别
                electronicMonitorTwoInfoVo.setPatientSex(patientBaseInfo.getPatientSex());
                // 出生日期
                electronicMonitorTwoInfoVo.setBirthdate(patientBaseInfo.getBirthdate());
                // 民族
                electronicMonitorTwoInfoVo.setNation(patientBaseInfo.getNation());
                // 联系方式
                electronicMonitorTwoInfoVo.setPhoneNo(patientBaseInfo.getPhoneNo());
            }
            electronicMonitorTwoInfoVo.setManageId(electronicManagerInfoVo.getId());
        } else {
            // 2.2 已入组
            Long monitorId = electronicManagerInfoVo.getMonitorId();
            if (ObjectUtil.isNull(monitorId)) {
                throw new ServiceException("已入组B表信息的监测id为空");
            }
            electronicMonitorTwoInfoVo = monitorTwoInfoMapper.selectVoById(monitorId);
            if (ObjectUtil.isNull(electronicMonitorTwoInfoVo)) {
                throw new ServiceException("已入组B表信息已不存在");
            }
            // 2.3 查询不良反应/事件记录信息
            List<ElectronicBadRecordInfoVo> electronicBadRecordInfoVoList = badRecordInfoMapper.selectVoList(new LambdaQueryWrapper<ElectronicBadRecordInfo>()
                .eq(ElectronicBadRecordInfo::getMonitorId, monitorId));
            electronicMonitorTwoInfoVo.setElectronicBadRecordInfoVoList(electronicBadRecordInfoVoList);
        }
        electronicMonitorTwoInfoVo.setManageId(electronicManagerInfoVo.getId());
        return electronicMonitorTwoInfoVo;
    }

    /**
     * 删除（B表）
     *
     * @param id 监测管理主键id
     * @return
     */
    @Transactional
    @Override
    public R<Void> deleteById2(Long id) {
        // 1.查询监测管理信息
        ElectronicManagerInfo electronicManagerInfo = baseMapper.selectById(id);
        // 2.删除监测管理信息
        boolean flag = baseMapper.deleteById(id) > 0;
        if (!flag) {
            throw new ServiceException("删除监测管理信息异常");
        }
        // 3.已入组
        Long monitorId = electronicManagerInfo.getMonitorId();
        /*if (ObjectUtil.isNull(monitorId)) {
            throw new ServiceException("没有查询到监测表id");
        }*/
        if (ObjectUtil.isNotNull(monitorId) && StringUtils.equals(electronicManagerInfo.getIsInputForm(), DictConstants.IS_INPUT_FORM_Y)) {
            // 3.1 删除B表信息
            flag = monitorTwoInfoMapper.deleteById(monitorId) > 0;
            if (!flag) {
                throw new ServiceException("删除B表信息异常");
            }
            // 3.2 删除不良反应/事件记录信息
            try {
                badRecordInfoMapper.delete(new LambdaQueryWrapper<ElectronicBadRecordInfo>()
                    .eq(ElectronicBadRecordInfo::getMonitorId, monitorId));
            } catch (Exception e) {
                throw new ServiceException("删除不良反应/事件记录异常");
            }
        }
        // 4.修改患者基本信息
        Integer medicalRecordNo = electronicManagerInfo.getMedicalRecordNo();
        List<ElectronicManagerInfo> electronicManagerInfoList = baseMapper.selectList(new LambdaQueryWrapper<ElectronicManagerInfo>()
            .eq(ElectronicManagerInfo::getMedicalRecordNo, medicalRecordNo));
        if (electronicManagerInfoList.size() == 0) {
            PatientBaseInfo patientBaseInfo = patientBaseInfoMapper.selectOne(new LambdaQueryWrapper<PatientBaseInfo>()
                .eq(PatientBaseInfo::getMedicalRecordNo, medicalRecordNo));
            patientBaseInfo.setIsHaveMonitor("0");
            flag = patientBaseInfoMapper.updateById(patientBaseInfo) > 0;
            if (!flag) {
                throw new ServiceException("修改患者信息失败");
            }
        }
        return R.ok("删除成功");
    }

    /**
     * 导出json
     *
     * @param response
     * @param ids      A表id集合
     */
    @Override
    public void exportJson(HttpServletResponse response, Long[] ids) throws IOException {
        // 1.查询监测A表数据
        List<ElectronicMonitorOneInfoVo> monitorOneInfoVoList = monitorOneInfoMapper.selectVoList(new LambdaQueryWrapper<ElectronicMonitorOneInfo>()
            .in(ElectronicMonitorOneInfo::getId, Arrays.asList(ids)));
        List<Long> exportMonitorIds = monitorOneInfoVoList.stream().map(ElectronicMonitorOneInfoVo::getId).collect(Collectors.toList());
        List<ElectronicExtendOneInfoVo> extendOneInfoVoList = extendOneInfoMapper.selectVoList(new LambdaQueryWrapper<ElectronicExtendOneInfo>()
            .in(ElectronicExtendOneInfo::getMonitorId, exportMonitorIds));
        Map<Long, List<ElectronicExtendOneInfoVo>> extendOneVoMap = extendOneInfoVoList.stream().collect(Collectors.groupingBy(ElectronicExtendOneInfoVo::getMonitorId));
        List<ElectronicExtendTwoInfoVo> extendTwoInfoVoList = extendTwoInfoMapper.selectVoList(new LambdaQueryWrapper<ElectronicExtendTwoInfo>()
            .in(ElectronicExtendTwoInfo::getMonitorId, exportMonitorIds));
        Map<Long, List<ElectronicExtendTwoInfoVo>> extendTwoVoMap = extendTwoInfoVoList.stream().collect(Collectors.groupingBy(ElectronicExtendTwoInfoVo::getMonitorId));
        monitorOneInfoVoList.stream().forEach(electronicMonitorOneInfoVo -> {
            Long monitorId = electronicMonitorOneInfoVo.getId();
            List<ElectronicExtendOneInfoVo> extendOneInfoVoToMonitorIdList = extendOneVoMap.get(monitorId);
            List<ElectronicExtendTwoInfoVo> extendTwoInfoVoToMonitorIdList = extendTwoVoMap.get(monitorId);
            if (ObjectUtil.isNull(extendOneInfoVoToMonitorIdList)) {
                electronicMonitorOneInfoVo.setElectronicExtendOneInfoVoList(new ArrayList<>());
            } else {
                electronicMonitorOneInfoVo.setElectronicExtendOneInfoVoList(extendOneInfoVoToMonitorIdList);
            }
            if (ObjectUtil.isNull(extendTwoInfoVoToMonitorIdList)) {
                electronicMonitorOneInfoVo.setElectronicExtendTwoInfoVoList(new ArrayList<>());
            } else {
                electronicMonitorOneInfoVo.setElectronicExtendTwoInfoVoList(extendTwoInfoVoToMonitorIdList);
            }
        });
        // 2.转化成符合EDC的类
        List<ExportMonitorJsonVo> edcJsonVoList = new ArrayList<>();
        monitorOneInfoVoList.stream().forEach(electronicMonitorOneInfoVo -> {
            ExportMonitorJsonVo exportMonitorJsonVo = new ExportMonitorJsonVo();
            BasicMonitorOneVo basic = new BasicMonitorOneVo();
            // 2.1 患者基本信息
            // 医院编号
            basic.setHospitalNo(StringUtils.isNotBlank(electronicMonitorOneInfoVo.getHospitalNo()) ? electronicMonitorOneInfoVo.getHospitalNo() : null);
            // 流水号
            basic.setSeqNo(ObjectUtil.isNotNull(electronicMonitorOneInfoVo.getMonitorRecordNo()) ? String.valueOf(electronicMonitorOneInfoVo.getMonitorRecordNo()) : null);
            // 住院号
            basic.setRegisterNo(StringUtils.isNotBlank(electronicMonitorOneInfoVo.getPatientNo()) ? StringUtils.padl(electronicMonitorOneInfoVo.getPatientNo(),10,'A') : null);
            // 姓名缩写
            basic.setName(StringUtils.isNotBlank(electronicMonitorOneInfoVo.getPatientNameAcronym()) ? electronicMonitorOneInfoVo.getPatientNameAcronym() : null);
            // 入组日期
            basic.setJoinDt(ObjectUtil.isNotNull(electronicMonitorOneInfoVo.getInputFormDate()) ? electronicMonitorOneInfoVo.getInputFormDate() : null);
            // 天气
            basic.setWeather(StringUtils.isNotBlank(electronicMonitorOneInfoVo.getWeather()) ? electronicMonitorOneInfoVo.getWeather() : null);
            // 温度
            basic.setTemper(StringUtils.isNotBlank(electronicMonitorOneInfoVo.getTemperature()) ? Double.parseDouble(electronicMonitorOneInfoVo.getTemperature()) : null);
            // 性别
            basic.setGender(StringUtils.isNotBlank(electronicMonitorOneInfoVo.getPatientSex()) ? Integer.parseInt(electronicMonitorOneInfoVo.getPatientSex()) : null);
            // 出生日期
            basic.setBirthday(ObjectUtil.isNotNull(electronicMonitorOneInfoVo.getBirthdate()) ? electronicMonitorOneInfoVo.getBirthdate() : null);
            // 体重
            basic.setWeight(electronicMonitorOneInfoVo.getPatientWeight() != null ? electronicMonitorOneInfoVo.getPatientWeight().doubleValue() : null);
            // 身高
            basic.setHeight(electronicMonitorOneInfoVo.getPatientHeight() != null ? electronicMonitorOneInfoVo.getPatientHeight().doubleValue() : null);
            // 民族
            if (StringUtils.equals(electronicMonitorOneInfoVo.getNation(), "汉族")) {
                basic.setNation(1);
                // 民族(其它)
                basic.setNationInfo(null);
            } else {
                basic.setNation(2);
                // 民族(其它)
                basic.setNationInfo(electronicMonitorOneInfoVo.getNation());
            }
            // 联系电话
            basic.setPhone(electronicMonitorOneInfoVo.getPhoneNo());
            // 是否有个人过敏史,0无,1有
            if (StringUtils.equals(electronicMonitorOneInfoVo.getIsHaveAllergy(), "0")) {
                basic.setIsAllergy(0);
                // 过敏原
                basic.setAllergySource(null);
                // 过敏原(其它)
                basic.setAllergySourceInfo(null);
                // 过敏表现
                basic.setAllergyShow(null);
                // 过敏表现(其它)
                basic.setAllergyShowInfo(null);
            } else {
                basic.setIsAllergy(1);
                // 过敏原
                String allergySource = StringUtils.isNotBlank(electronicMonitorOneInfoVo.getAllergySource()) ? electronicMonitorOneInfoVo.getAllergySource() : null;
                basic.setAllergySource(allergySource);
                if (ObjectUtil.isNotNull(allergySource)) {
                    // 过敏原(其它)
                    List<String> split = Arrays.asList(allergySource.split(","));
                    List<String> split2 = new ArrayList<>();
                    split.stream().forEach(s -> {
                        switch (s) {
                            case "1":
                                split2.add(s + "-" + electronicMonitorOneInfoVo.getAllergyFood());
                                break;
                            case "2":
                                split2.add(s + "-" + electronicMonitorOneInfoVo.getAllergyDrug());
                                break;
                            case "3":
                                split2.add(s + "-" + electronicMonitorOneInfoVo.getAllergyUnknown());
                                break;
                            case "4":
                                split2.add(s + "-" + electronicMonitorOneInfoVo.getAllergyOther());
                            default:
                                break;
                        }
                    });
                    basic.setAllergySourceInfo(StringUtils.join(split2, ","));
                } else {
                    // 过敏原(其它)
                    basic.setAllergySourceInfo(null);
                }
                // 过敏表现
                String allergyShow = StringUtils.isNotBlank(electronicMonitorOneInfoVo.getAllergyShow()) ? electronicMonitorOneInfoVo.getAllergyShow() : null;
                basic.setAllergyShow(allergyShow);
                if (ObjectUtil.isNotNull(allergyShow)) {
                    // 过敏表现(其它)
                    List<String> split = Arrays.asList(allergyShow.split(","));
                    List<String> split2 = new ArrayList<>();
                    split.stream().forEach(s -> {
                        switch (s) {
                            case "1":
                            case "2":
                            case "3":
                            case "4":
                            case "5":
                            case "6":
                            case "7":
                            case "8":
                            case "9":
                            case "10":
                                split2.add(s + "-");
                                break;
                            case "11":
                                split2.add(s + "-" + electronicMonitorOneInfoVo.getAllergyShowOther());
                                break;
                            default:
                                break;
                        }
                    });
                    basic.setAllergyShowInfo(StringUtils.join(split2, ","));
                } else {
                    // 过敏表现(其它)
                    basic.setAllergyShowInfo(null);
                }
            }
            // 是否有过敏性疾病史,0无,1有
            if (StringUtils.equals(electronicMonitorOneInfoVo.getIsHaveIllness(), "0")) {
                basic.setIsAllergicDisease(0);
                // 过敏性疾病
                basic.setAllergicDisease(null);
                // 过敏性疾病(其它)
                basic.setAllergicDiseaseInfo(null);
            } else {
                basic.setIsAllergicDisease(1);
                // 过敏性疾病
                String illnessShow = StringUtils.isNotBlank(electronicMonitorOneInfoVo.getIllnessShow()) ? electronicMonitorOneInfoVo.getIllnessShow() : null;
                basic.setAllergicDisease(illnessShow);
                // 过敏性疾病(其它)
                if (ObjectUtil.isNotNull(illnessShow)) {
                    List<String> split = Arrays.asList(illnessShow.split(","));
                    List<String> split2 = new ArrayList<>();
                    split.stream().forEach(s -> {
                        switch (s) {
                            case "1":
                            case "2":
                            case "3":
                            case "4":
                                split2.add(s + "-");
                                break;
                            case "5":
                                split2.add(s + "-" + electronicMonitorOneInfoVo.getIllnessShowOther());
                                break;
                            default:
                                break;
                        }
                    });
                    basic.setAllergicDiseaseInfo(StringUtils.join(split2, ","));
                } else {
                    basic.setAllergicDiseaseInfo(null);
                }
            }
            // 是否有家族过敏史,0无,1有
            if (StringUtils.equals(electronicMonitorOneInfoVo.getIsHaveFamily(), "0")) {
                basic.setIsFamilyAllergy(0);
                // 家族过敏史与本人关系-父母,0无,1有
                basic.setIsParentAllergy(null);
                // 家族过敏史与本人关系-兄弟姐妹,0无,1有
                basic.setIsBrotherAllergy(null);
            } else {
                basic.setIsFamilyAllergy(1);
                // 家族过敏史与本人关系-父母,0无,1有
                basic.setIsParentAllergy(StringUtils.isNotBlank(electronicMonitorOneInfoVo.getRelationParent()) ? Integer.parseInt(electronicMonitorOneInfoVo.getRelationParent()) : null);
                // 家族过敏史与本人关系-兄弟姐妹,0无,1有
                basic.setIsBrotherAllergy(StringUtils.isNotBlank(electronicMonitorOneInfoVo.getRelationBrotherSister()) ? Integer.parseInt(electronicMonitorOneInfoVo.getRelationBrotherSister()) : null);
            }
            // 家族过敏史药物,0无,1有
            if (StringUtils.equals(electronicMonitorOneInfoVo.getRelationPills(), "0")) {
                basic.setFamilyAllergyMedi(0);
                // 家族过敏史药物(有)
                basic.setFamilyAllergyMediInfo(null);
            } else {
                basic.setFamilyAllergyMedi(1);
                // 家族过敏史药物(有)
                basic.setFamilyAllergyMediInfo(StringUtils.isNotBlank(electronicMonitorOneInfoVo.getRelationPillsHave()) ? electronicMonitorOneInfoVo.getRelationPillsHave() : null);
            }
            // 家族其它过敏史,0无,1有
            if (StringUtils.equals(electronicMonitorOneInfoVo.getRelationAllergyOther(), "0")) {
                basic.setFamilyOtherAllergy(0);
                // 家族其它过敏史(有)
                basic.setFamilyOtherAllergyInfo(null);
            } else {
                basic.setFamilyOtherAllergy(1);
                // 家族其它过敏史(有)
                basic.setFamilyOtherAllergyInfo(StringUtils.isNotBlank(electronicMonitorOneInfoVo.getRelationAllergyOtherHave()) ? electronicMonitorOneInfoVo.getRelationAllergyOtherHave() : null);
            }
            // 西医诊断
            String westernMedicineDiagnose = StringUtils.isNotBlank(electronicMonitorOneInfoVo.getWesternMedicineDiagnose()) ? electronicMonitorOneInfoVo.getWesternMedicineDiagnose() : null;
            basic.setWesternDiagnosis(westernMedicineDiagnose);
            // 西医诊断(其它)
            if (ObjectUtil.isNotNull(westernMedicineDiagnose)) {
                List<String> split = Arrays.asList(westernMedicineDiagnose.split(","));
                List<String> split2 = new ArrayList<>();
                split.stream().forEach(s -> {
                    switch (s) {
                        case "1":
                        case "2":
                        case "3":
                        case "4":
                        case "5":
                        case "6":
                        case "7":
                        case "8":
                        case "9":
                            split2.add(s + "-");
                            break;
                        case "10":
                            split2.add(s + "-" + electronicMonitorOneInfoVo.getWesternMedicineDiagnoseOther());
                            break;
                        default:
                            break;
                    }
                });
                basic.setWesternDiagnosisInfo(StringUtils.join(split2, ","));
            } else {
                basic.setWesternDiagnosisInfo(null);
            }
            // 是否有中医诊断,0无,1有
            if (StringUtils.equals(electronicMonitorOneInfoVo.getIsHaveTcmDiagnose(), "0")) {
                basic.setIsChinaDiagnosis(0);
                // 中医诊断
                basic.setChinaDiagnosis(null);
                // 中医诊断(其它)
                basic.setChinaDiagnosisInfo(null);
            } else {
                basic.setIsChinaDiagnosis(1);
                // 中医诊断
                String tcmDiagnose = StringUtils.isNotBlank(electronicMonitorOneInfoVo.getTcmDiagnose()) ? electronicMonitorOneInfoVo.getTcmDiagnose() : null;
                basic.setChinaDiagnosis(tcmDiagnose);
                // 中医诊断(其它)
                if (ObjectUtil.isNotNull(tcmDiagnose)) {
                    List<String> split = Arrays.asList(tcmDiagnose.split(","));
                    List<String> split2 = new ArrayList<>();
                    split.stream().forEach(s -> {
                        switch (s) {
                            case "1":
                            case "2":
                                split2.add(s + "-");
                                break;
                            case "3":
                                split2.add(s + "-" + electronicMonitorOneInfoVo.getTcmDiagnoseOther());
                                break;
                            default:
                                break;
                        }
                    });
                    basic.setChinaDiagnosisInfo(StringUtils.join(split2, ","));
                } else {
                    basic.setChinaDiagnosisInfo(null);
                }
            }
            // 是否辨证,0无,1有
            if (StringUtils.equals(electronicMonitorOneInfoVo.getIsHavaDialectical(), "0")) {
                basic.setIsDialectic(0);
                // 辨证(有)
                basic.setDialecticInfo(null);
            } else {
                basic.setIsDialectic(1);
                // 辨证(有)
                basic.setDialecticInfo(StringUtils.isNotBlank(electronicMonitorOneInfoVo.getDialecticalDetail()) ? electronicMonitorOneInfoVo.getDialecticalDetail() : null);
            }
            // 入院诊断（西医）
            basic.setWesternAdmissionDiagnosis(StringUtils.isNotBlank(electronicMonitorOneInfoVo.getWesternAdmittingDiagnose()) ? electronicMonitorOneInfoVo.getWesternAdmittingDiagnose().replace("；", "-") : null);
            // 是否有入院诊断（中医）,0无,1有
            if (StringUtils.equals(electronicMonitorOneInfoVo.getIsHaveTcmAdmittingDiagnose(), "0")) {
                basic.setIsChinaAdmissionDiagnosis(0);
                // 入院诊断（中医）(有)
                basic.setChinaAdmissionDiagnosis(null);
            } else {
                basic.setIsChinaAdmissionDiagnosis(1);
                // 入院诊断（中医）(有)
                basic.setChinaAdmissionDiagnosis(StringUtils.isNotBlank(electronicMonitorOneInfoVo.getTcmAdmittingDiagnose()) ? electronicMonitorOneInfoVo.getTcmAdmittingDiagnose() : null);
            }
            // 入院诊断（中医）辨证,0无,1有
            if (StringUtils.equals(electronicMonitorOneInfoVo.getIsHaveAdmittingDialectical(), "0")) {
                basic.setIsDialecticAdmissionDiagnosis(0);
                // 入院诊断（中医）辨证(有)
                basic.setDialecticAdmissionDiagnosis(null);
            } else {
                basic.setIsDialecticAdmissionDiagnosis(1);
                // 入院诊断（中医）辨证(有)
                basic.setDialecticAdmissionDiagnosis(StringUtils.isNotBlank(electronicMonitorOneInfoVo.getAdmittingDialecticalDetail()) ? electronicMonitorOneInfoVo.getAdmittingDialecticalDetail() : null);
            }
            // 本次治疗前是否使用过舒血宁,0否,1是,2不详
            basic.setDrugBefore(StringUtils.isNotBlank(electronicMonitorOneInfoVo.getIsHavaUse()) ? Integer.parseInt(electronicMonitorOneInfoVo.getIsHavaUse()) : null);
            // 监测期内用药天数
            basic.setDrugDuration(electronicMonitorOneInfoVo.getUseDays() != null ? electronicMonitorOneInfoVo.getUseDays() : null);
            // 首次用药时间
            basic.setDrugFirstDt(electronicMonitorOneInfoVo.getFirstUseDate() != null ? electronicMonitorOneInfoVo.getFirstUseDate() : null);
            // 末次用药时间
            basic.setDrugLastDt(electronicMonitorOneInfoVo.getLastUseDate() != null ? electronicMonitorOneInfoVo.getLastUseDate() : null);
            // 给药期间是否发生不良反应事件
            basic.setIsAdr(StringUtils.isNotBlank(electronicMonitorOneInfoVo.getIsHaveBad()) ? Integer.parseInt(electronicMonitorOneInfoVo.getIsHaveBad()) : null);
            exportMonitorJsonVo.setBasic(basic);
            // 2.2 A表监测信息表（续一）
            List<ElectronicExtendOneInfoVo> electronicExtendOneInfoVoList = electronicMonitorOneInfoVo.getElectronicExtendOneInfoVoList();
            List<DailyMedicalVo> dailyMedicalVoList = new ArrayList<>();
            electronicExtendOneInfoVoList.stream().forEach(electronicExtendOneInfoVo -> {
                DailyMedicalVo dailyMedicalVo = new DailyMedicalVo();
                // 给药开始时间
                dailyMedicalVo.setStartDt(electronicExtendOneInfoVo.getBeginTime());
                // 批号
                dailyMedicalVo.setBatchNo(electronicExtendOneInfoVo.getBatchNo());
                // 配液放置时间（min）
                dailyMedicalVo.setLiquidMixTime(StringUtils.isNotBlank(electronicExtendOneInfoVo.getPlaceTime()) ? Integer.parseInt(electronicExtendOneInfoVo.getPlaceTime()) : null);
                // 给药频率（次/天）
                dailyMedicalVo.setFrequency(StringUtils.isNotBlank(electronicExtendOneInfoVo.getFrequency()) ? Integer.parseInt(electronicExtendOneInfoVo.getFrequency()) : null);
                // 单次用药量
                dailyMedicalVo.setQuantityOnce(StringUtils.isNotBlank(electronicExtendOneInfoVo.getSingleAmount()) ? Double.parseDouble(electronicExtendOneInfoVo.getSingleAmount()) : null);
                // 溶媒种类
                dailyMedicalVo.setMenstruum(StringUtils.isNotBlank(electronicExtendOneInfoVo.getMenstruumType()) ? Integer.parseInt(electronicExtendOneInfoVo.getMenstruumType()) : null);
                // 溶媒种类(其它)
                dailyMedicalVo.setMenstruumInfo(StringUtils.isNotBlank(electronicExtendOneInfoVo.getMenstruumTypeOther()) ? electronicExtendOneInfoVo.getMenstruumTypeOther() : null);
                // 次溶媒剂量（ml）
                dailyMedicalVo.setMenstruumOnceQuantity(StringUtils.isNotBlank(electronicExtendOneInfoVo.getSingleMenstruumAmount()) ? Double.parseDouble(electronicExtendOneInfoVo.getSingleMenstruumAmount()) : null);
                // 给药途径
                dailyMedicalVo.setDrugMode(StringUtils.isNotBlank(electronicExtendOneInfoVo.getGiveIllnessPathway()) ? Integer.parseInt(electronicExtendOneInfoVo.getGiveIllnessPathway()) : null);
                // 给药途径(其它)
                dailyMedicalVo.setDrugModeInfo(StringUtils.isNotBlank(electronicExtendOneInfoVo.getGiveIllnessPathwayOther()) ? electronicExtendOneInfoVo.getGiveIllnessPathwayOther() : null);
                // 静滴速度（滴/min）
                dailyMedicalVo.setSpeed(StringUtils.isNotBlank(electronicExtendOneInfoVo.getQuietSpeed()) ? Integer.parseInt(electronicExtendOneInfoVo.getQuietSpeed().trim()) : null);
                // 静滴持续时间（min）
                dailyMedicalVo.setDuration(StringUtils.isNotBlank(electronicExtendOneInfoVo.getQuietContinueTime()) ? Integer.parseInt(electronicExtendOneInfoVo.getQuietContinueTime().trim()) : null);
                dailyMedicalVoList.add(dailyMedicalVo);
            });
            exportMonitorJsonVo.setDailyMedi(dailyMedicalVoList);
            // todo 2.3 A表合并用药情况表（续二）
            List<ElectronicExtendTwoInfoVo> electronicExtendTwoInfoVoList = electronicMonitorOneInfoVo.getElectronicExtendTwoInfoVoList();
            List<CombindMedicalVo> combindMedicalVoList = new ArrayList<>();
            electronicExtendTwoInfoVoList.stream().forEach(electronicExtendTwoInfoVo -> {
                CombindMedicalVo combindMedicalVo = new CombindMedicalVo();
                // 药品名称
                combindMedicalVo.setName(electronicExtendTwoInfoVo.getPillsName());
                // 给药途径
                combindMedicalVo.setDrugMode(StringUtils.isNotBlank(electronicExtendTwoInfoVo.getGivePillsPathway()) ? Integer.parseInt(electronicExtendTwoInfoVo.getGivePillsPathway()) : null);
                // 给药途径(其它)
                combindMedicalVo.setDrugModeInfo(StringUtils.isNotBlank(electronicExtendTwoInfoVo.getGivePillsPathwayOther()) ? electronicExtendTwoInfoVo.getGivePillsPathwayOther() : null);
                // 用法
                combindMedicalVo.setDrugUseMethod(StringUtils.isNotBlank(electronicExtendTwoInfoVo.getPillsUsage()) ? Integer.parseInt(electronicExtendTwoInfoVo.getPillsUsage()) : null);
                // 用法(其它)
                combindMedicalVo.setDrugUseMethodInfo(StringUtils.isNotBlank(electronicExtendTwoInfoVo.getPillsUsageOther()) ? electronicExtendTwoInfoVo.getPillsUsageOther() : null);
                // 用量
                combindMedicalVo.setDosage(electronicExtendTwoInfoVo.getPillsAmount());
                // 研究结束时
                combindMedicalVo.setEndSign(StringUtils.isNotBlank(electronicExtendTwoInfoVo.getEndTime()) ? Integer.parseInt(electronicExtendTwoInfoVo.getEndTime()) : null);
                combindMedicalVoList.add(combindMedicalVo);
            });
            exportMonitorJsonVo.setCombindMedi(combindMedicalVoList);
            edcJsonVoList.add(exportMonitorJsonVo);
        });
        // 3.导出压缩文件
        response.reset();
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("A表监测信息", "UTF-8") + ".zip");
        response.setContentType("application/octet-stream; charset=UTF-8");
        ZipOutputStream zos = null;
        try {
            zos = new ZipOutputStream(response.getOutputStream());
            for (int i = 0; i < edcJsonVoList.size(); i++) {
                try {
                    ExportMonitorJsonVo exportMonitorJsonVo = edcJsonVoList.get(i);
                    //获取文件名
                    String originalName = exportMonitorJsonVo.getBasic().getSeqNo() + ".json";
                    String jsonStr = objectMapper.writeValueAsString(exportMonitorJsonVo);
                    byte[] jsonBytes = jsonStr.getBytes(StandardCharsets.UTF_8);
                    ZipEntry entry = new ZipEntry(originalName);
                    zos.putNextEntry(entry);
                    int len = 0;
                    //设置缓冲大小
                    byte[] buffer = new byte[1024];
                    // 得到字节流
                    InputStream fis = new ByteArrayInputStream(jsonBytes);
                    while ((len = fis.read(buffer)) > 0) {
                        zos.write(buffer, 0, len);
                    }
                    zos.flush();
                    zos.closeEntry();
                    fis.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (zos != null) {
                zos.close();
            }
        }
        // 4.修改导出状态
        try {
            monitorOneInfoVoList.stream().forEach(electronicMonitorOneInfoVo -> {
                electronicMonitorOneInfoVo.setExportStatus("1");
            });
            List<ElectronicMonitorOneInfo> electronicMonitorOneInfoList = BeanUtil.copyToList(monitorOneInfoVoList, ElectronicMonitorOneInfo.class);
            monitorOneInfoMapper.insertOrUpdateBatch(electronicMonitorOneInfoList);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServerException("修改导出状态失败");
        }
    }
}
